//答案1(运气版)
//全局锁现象数据不一致问题
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<cstring>
#include<unistd.h>
#include<pthread.h>
int ticket = 100;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;//初始化定义锁
pthread_cond_t glock = PTHREAD_COND_INITIALIZER;//定义条件变量
void* route(void* arg)
{
    char* id = (char*) arg;
    while(true)
    {
        pthread_mutex_lock(&lock);//加锁
        pthread_cond_wait(&glock,&lock);//条件变量等待
        if(ticket > 0)
        {
            usleep(1000);
            printf("%s sells ticket: %d\n",id,ticket);
            ticket--;
            pthread_mutex_unlock(&lock);//解锁
        }
        else
        {
            pthread_mutex_unlock(&lock);//解锁
            break;
        }
    }
    return nullptr;
}
int main()
{
    pthread_t t1,t2,t3,t4;
    //创建四个线程
    pthread_create(&t1,nullptr,route,(void*)"thread 1");
    //sleep(1);
    pthread_create(&t2,nullptr,route,(void*)"thread 2");
    //sleep(1);
    pthread_create(&t3,nullptr,route,(void*)"thread 3");
    //sleep(1);
    pthread_create(&t4,nullptr,route,(void*)"thread 4");
    //sleep(3);
    while(true)
    {
        //pthread_mutex_lock(&lock);//加锁
        
        
        pthread_mutex_lock(&lock);//加锁
        if(ticket == 0)
        {
            pthread_mutex_unlock(&lock);//解锁
            break;
        }
        

        pthread_cond_signal(&glock);//将线程逐个唤醒,实现同步效果,解决线程饥饿问题

       pthread_mutex_unlock(&lock);//解锁
    }
    sleep(2);//确保所有进程全部都(存在一定的运气成分,如果线程非常多,两秒也不能使全部的线程进入条件等待,此时这种方法不可取,但通常不会有这种可能的存在)
    pthread_mutex_lock(&lock);//加锁
    //一定要等待所有线程进入条件等待状态后才能唤醒全部线程,不然会可能出现bug卡
    pthread_cond_broadcast(&glock);//将条件变量下的所有线程全部唤醒,让他们去锁上阻塞等待
    pthread_mutex_unlock(&lock);//解锁
    //回收四个线程
    pthread_join(t1,nullptr);
    std::cout << "1" << std::endl;
    //sleep(1);
    pthread_join(t2,nullptr);
    std::cout << "2" << std::endl;
    //sleep(1);
    pthread_join(t3,nullptr);
    std::cout << "3" << std::endl;
    //sleep(1);
    pthread_join(t4,nullptr);
    std::cout << "4" << std::endl;
    return 0;
}
/*
//答案二
//全局锁现象数据不一致问题
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<cstring>
#include<unistd.h>
#include<pthread.h>
int ticket = 100;
int num = 0;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;//初始化定义锁
pthread_cond_t glock = PTHREAD_COND_INITIALIZER;//定义条件变量
void* route(void* arg)
{
    char* id = (char*) arg;
    while(true)
    {
        pthread_mutex_lock(&lock);//加锁
        num++;
        std::cout << num << std::endl;
        pthread_cond_wait(&glock,&lock);//条件变量等待
        if(ticket > 0)
        {
            usleep(1000);
            printf("%s sells ticket: %d\n",id,ticket);
            ticket--;
            num--;
            pthread_mutex_unlock(&lock);//解锁
        }
        else
        {
            //num--;
            pthread_mutex_unlock(&lock);//解锁
            break;
        }
    }
    return nullptr;
}
int main()
{
    pthread_t t1,t2,t3,t4;
    //创建四个线程
    pthread_create(&t1,nullptr,route,(void*)"thread 1");
    //sleep(1);
    pthread_create(&t2,nullptr,route,(void*)"thread 2");
    //sleep(1);
    pthread_create(&t3,nullptr,route,(void*)"thread 3");
    //sleep(1);
    pthread_create(&t4,nullptr,route,(void*)"thread 4");
    //sleep(3);
    while(true)
    {
        //pthread_mutex_lock(&lock);//加锁(这里的锁一定要加,不然当unlock为0的时候,break跳出循环后,假设有三个线程需要释放,下面将线程全部唤醒,)
        
        {
            pthread_mutex_lock(&lock);//加锁
            if(ticket == 0)
            {
                pthread_mutex_unlock(&lock);//解锁
                break;
            }
            pthread_mutex_unlock(&lock);//解锁
        }

        pthread_cond_signal(&glock);//将线程逐个唤醒,实现同步效果,解决线程饥饿问题

       //pthread_mutex_unlock(&lock);//解锁
    }
    while(true)
    {
        pthread_mutex_lock(&lock);//加锁

        if(num == 4)
        {
            pthread_cond_broadcast(&glock);//将条件变量下的所有线程全部唤醒,让他们去锁上阻塞等待
            pthread_mutex_unlock(&lock);//解锁

            break;
        }
        pthread_mutex_unlock(&lock);//解锁
        
    }
    //回收四个线程
    pthread_join(t1,nullptr);
    std::cout << "1" << std::endl;
    //sleep(1);
    pthread_join(t2,nullptr);
    std::cout << "2" << std::endl;
    //sleep(1);
    pthread_join(t3,nullptr);
    std::cout << "3" << std::endl;
    //sleep(1);
    pthread_join(t4,nullptr);
    std::cout << "4" << std::endl;
    return 0;
}
*/